package Test;

/**
 * 懒汉式加载： 只有调用getInstance()才实例化
 * 
 * @author Administrator
 * 
 *         需要注意的点： 1. 构造函数必须是：private  （阻止外部使用new 关键字来创建）
 * 
 */
public class LazySingleton {
	/**
	 * 初始为null，暂不实例化
	 * */
	private static LazySingleton lazySingletonInstance = null;

	/** private 阻止外部使用new实例化对象 */
	private LazySingleton() {
	}

	/**
	 * 只有在调用getInstance()时此类才会被装载 　　* 在SingletonKerriganF.java中说明了加载顺序
	 */

	private static class SingletonHolder {
		/**
		 * 对象实例, jvm保证只初始化一次
		 */
	     static final LazySingleton lazySingletonInstance = new LazySingleton();
	}

	// 必须考虑线程同步的问题！
	public synchronized static LazySingleton getInstance() {
		if (lazySingletonInstance == null) {
			System.out.println("LazySingleton initial.........");
			lazySingletonInstance = new LazySingleton();
		}

		// 模式一
		return lazySingletonInstance;
		// 模式二
		// return SingletonHolder.lazySingletonInstance;
	}

	public static void main(String[] args) {
		System.out.println("getInstance.........");
		LazySingleton.getInstance();
	}
}

// ==========================
/**
 * 在上面给出懒汉式单例类实现里对静态工厂方法使用了同步化，以处理多线程环境。有些设计师在这里
 * 
 * 建议使用所谓的"双重检查成例".必须指出的是，"双重检查成例"不可以在Java 语言中使用。不十分熟
 * 
 * 悉的读者，可以看看后面给出的小节。
 * 
 * 　　同样，由于构造子是私有的，因此，此类不能被继承。饿汉式单例类在自己被加载时就将自己实例
 * 
 * 化。即便加载器是静态的，在饿汉式单例类被加载时仍会将自己实例化。单从资源利用效率角度来讲，
 * 
 * 这个比懒汉式单例类稍差些。
 * 
 * 　　从速度和反应时间角度来讲，则比懒汉式单例类稍好些。然而，懒汉式单例类在实例化时，必须处
 * 
 * 理好在多个线程同时首次引用此类时的访问限制问题，特别是当单例类作为资源控制器，在实例化时必
 * 
 * 然涉及资源初始化，而资源初始化很有可能耗费时间。这意味着出现多线程同时首次引用此类的机率变
 * 
 * 得较大。
 * 
 * 　　饿汉式单例类可以在Java 语言内实现， 但不易在C++ 内实现，因为静态初始化在C++ 里没有固定
 * 
 * 的顺序，因而静态的m_instance 变量的初始化与类的加载顺序没有保证，可能会出问题。这就是为什么
 * 
 * GoF 在提出单例类的概念时，举的例子是懒汉式的。他们的书影响之大，以致Java 语言中单例类的例子
 * 
 * 也大多是懒汉式的。实际上，本书认为饿汉式单例类更符合Java 语言本身的特点。
 */
